#define   NONAMELESSUNION
#include <windows.h>

/*
http://forums.codeguru.com/showthread.php?377394-Windows-SDK-User-Interface-How-can-I-emulate-mouse-events-in-an-application
*/

HINSTANCE g_hInstance;


BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID) 
{
	if (fdwReason == DLL_PROCESS_ATTACH) {
		g_hInstance = hInstance;
	}
	return TRUE;
}


STDAPI __export STDCALL_MOVE(WORD, DISPPARAMS FAR* pDispParams, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
	if (pDispParams->cArgs < 2) return DISP_E_BADPARAMCOUNT;
		
	double fScreenWidth = GetSystemMetrics( SM_CXSCREEN ) - 1; 
	double fScreenHeight = GetSystemMetrics( SM_CYSCREEN ) - 1; 
	
	VARIANT X;
	VariantInit(&X);
	VariantCopyInd(&X, &pDispParams->rgvarg[1]);
	HRESULT hr = VariantChangeType(&X, &X, 0, VT_I4);
	if FAILED(hr) return hr;
	int x = X.n1.n2.n3.lVal;
	
	VARIANT Y;
	VariantInit(&Y);
	VariantCopyInd(&Y, &pDispParams->rgvarg[0]);
	hr = VariantChangeType(&Y, &Y, 0, VT_I4);
	if FAILED(hr) return hr;
	int y = Y.n1.n2.n3.lVal;
	
	double fx = x*(65535.0f/fScreenWidth);
	double fy = y*(65535.0f/fScreenHeight);	
	INPUT  Input = {0};
	Input.type      = INPUT_MOUSE;
	Input.mi.dwFlags  = MOUSEEVENTF_MOVE|MOUSEEVENTF_ABSOLUTE;
	Input.mi.dx = fx;
	Input.mi.dy = fy;
	
	pRes->n1.n2.vt = VT_I4;
	pRes->n1.n2.n3.lVal = SendInput(1,&Input, sizeof(INPUT));
	return S_OK;
}

void Click(DWORD down, DWORD up) {
	INPUT    Input={0};
	// left down 
	Input.type      = INPUT_MOUSE;
	Input.mi.dwFlags  = down;
	SendInput(1,&Input,sizeof(INPUT));

	// left up
	ZeroMemory(&Input,sizeof(INPUT));
	Input.type      = INPUT_MOUSE;
	Input.mi.dwFlags  = up;
	SendInput(1,&Input,sizeof(INPUT));	
}

STDAPI __export STDCALL_LEFTCLICK(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
	Click(MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP);
  
	pRes->n1.n2.vt = VT_BOOL;
	pRes->n1.n2.n3.boolVal = TRUE;
	
	return S_OK;
}

STDAPI __export STDCALL_RIGHTCLICK(WORD, DISPPARAMS FAR*, VARIANT FAR* pRes, EXCEPINFO FAR*) 
{
	
	Click(MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP);
	
	pRes->n1.n2.vt = VT_BOOL;
	pRes->n1.n2.n3.boolVal = TRUE;
	
	return S_OK;
}
